package cn.laike.common.utils.wxpay;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

import com.alibaba.fastjson.JSON;

import cn.laike.common.utils.HttpRequest;
import cn.laike.common.utils.XMLUtils;






public class WxPayHelper {
	
	private HashMap<String, String> parameters = new HashMap<String, String>();
	private String AppId = "";
	private String MchId = "";
	private String ApiKey = "";
	
	public void SetParameter(String key, String value) {
		parameters.put(key, value);
	}

	public String GetParameter(String key) {
		return parameters.get(key);
	}
	
	
	
	public void setAppId(String appId) {
		AppId = appId;
	}


	public void setMchId(String mchId) {
		MchId = mchId;
	}


	public void setApiKey(String apiKey) {
		ApiKey = apiKey;
	}


	
	
	
	/**
	 
	 	HashMap<String, String> map = new HashMap<String, String>();
		 map.put("appid", "");//微信分配的公众账号 ID
         map.put("mch_id", "");//微信支付 分配的商户号
         map.put("nonce_str", "");//随机字符串
         map.put("body", "");//商品描述
         map.put("out_trade_no", "");//商户系统内部的订单号
         map.put("total_fee", "");//订单总金额  单位为分
         map.put("spbill_create_ip", "");//订单生成的机器
         map.put("notify_url", "");//接收微信支付成功通知
         map.put("trade_type", "NATIVE");//JSAPI  、  NATIVE   、 APP
         map.put("product_id", "");//只在  trade_type    为      NATIVE 时需要填写。此 id   为二维码 中包含的商品 ID ，商户自行维护。
         map.put("openid", "");//用户在商户   appid  下的唯一  标识，  trade_type    为  JSAPI   时，此参数必传，获取方式   见表头说明。      
         
         //可以不传的
         map.put("device_info", "");//微信支付分配的终端设备号
         map.put("attach", "");//附加数据，原样返回
         map.put("goods_tag", "");//商品标记
         map.put("time_start", "");//订 单 生 成 时 间 ， 格 式 为yyyyMMddHHmmss
         map.put("time_expire", "");//订 单 失 效 时 间， 格 式 为yyyyMMddHHmmss
	 
	 *@author xiaoqian
	 * @param map
	 * @return
	 * 2014-11-11上午10:54:10
	 */
	public String formatParam(HashMap<String, String> map,String key){
		String str= "";
		StringBuffer sb  = new StringBuffer();
		try {
			String param = CommonUtil.FormatBizQueryParaMap(map,false,true);
			
			String sign = MD5SignUtil.Sign(param, key);
			
			
			System.out.println(MD5SignUtil.VerifySignature(param, sign, key));
			
			map.put("sign", sign);
			str = XMLUtils.maptoXml(map);
			
//			sb.append("<xml>");
//			sb.append("\t").append("<sign>"+map.get("sign")+"</sign>").append("\n");
//			sb.append("\t").append("<mch_id>"+map.get("mch_id")+"</mch_id>").append("\n");
//			sb.append("\t").append("<body><![CDATA["+map.get("body")+"]]></body>").append("\n");
//			sb.append("\t").append("<total_fee>"+map.get("total_fee")+"</total_fee>").append("\n");
//			sb.append("\t").append("<spbill_create_ip>"+map.get("spbill_create_ip")+"</spbill_create_ip>").append("\n");
//			sb.append("\t").append("<notify_url>"+map.get("notify_url")+"</notify_url>").append("\n");
//			sb.append("\t").append("<appid>"+map.get("appid")+"</appid>").append("\n");
//			sb.append("\t").append("<openid>"+map.get("openid")+"</openid>").append("\n");
//			sb.append("\t").append("<out_trade_no>"+map.get("out_trade_no")+"</out_trade_no>").append("\n");
//			sb.append("\t").append("<nonce_str>"+map.get("nonce_str")+"</nonce_str>").append("\n");
//			sb.append("\t").append("<trade_type>"+map.get("trade_type")+"</trade_type>").append("\n");
//			sb.append("</xml>");
			
			
			
		} catch (SDKRuntimeException e) {
			e.printStackTrace();
		}
		
		return str;
	}
	
	
	
	/**
	 * 用于Native支付

	 *@author xiaoqian
	 * @param appid
	 * @param key
	 * @param product_id
	 * @param mch_id
	 * @return
	 * @throws SDKRuntimeException
	 * 2014-11-11下午2:04:42
	 */
	public String createPayUrl(String product_id) throws SDKRuntimeException{
		String str ="weixin://wxpay/bizpayurl?";
		String st = CommonUtil.CreateNoncestr();
		
		HashMap<String, String> map = new HashMap<String, String>();
        map.put("appid", AppId);
        map.put("mch_id", MchId);
        map.put("nonce_str", st);
        map.put("product_id",product_id);
        map.put("time_stamp",System.currentTimeMillis()+"");
        
        
        String param = CommonUtil.FormatBizQueryParaMap(map,false,true);
		String sign = MD5SignUtil.Sign(param, ApiKey);
		return str+param+"&sign="+sign;
	}
	
	
	
	
	/**
	 * 根据商家订单号查找支付订单是否交易成功
	 * @return
	 * @throws Exception
	 */
	public Map<String, String> findPayUrlByJSAPI() throws Exception{
		init(parameters);
        String xmlParam = formatParam(parameters, ApiKey);
        System.out.println(xmlParam);
        String result = HttpRequest.postXml("https://api.mch.weixin.qq.com/pay/orderquery", xmlParam);
        Map<String, String> xmlMap =  XMLUtils.xml2Map(result);
        
        Map<String,String> params =  new HashMap<String, String>();
        
        params.put("return_code", xmlMap.get("xml.return_code"));//请求是否成功
        params.put("return_msg", xmlMap.get("xml.return_msg"));//请求描述
        params.put("result_code", xmlMap.get("xml.result_code"));//交易是否成功
        
        params.put("trade_state", xmlMap.get("xml.trade_state"));//交易状态码【SUCCESS—支付成功，REFUND—转入退款，NOTPAY—未支付，CLOSED—已关闭，REVOKED—已撤销（刷卡支付），USERPAYING--用户支付中，PAYERROR--支付失败(其他原因，如银行返回失败)】
        params.put("transaction_id", xmlMap.get("xml.transaction_id"));//交易成功的微信支付单号
        
        params.put("err_code", xmlMap.get("xml.err_code"));//交易失败后的交易码
        params.put("err_code_des", xmlMap.get("xml.err_code_des"));//交易失败后的描述
        
		return params;
	}
	
	
	
	
	
	/**
	 * 传入参数
	 *@author xiaoqian
	 * @param parameters
	 * 2014-11-11下午5:07:25
	 */
	public void init( HashMap<String, String> parameters ){
		parameters.put("appid", AppId);
		parameters.put("mch_id", MchId);
	}
	
	public String getPayUrl() throws Exception{
		
		init(parameters);
		
		String test ="\n\n<xml>\n   <sign>0B382B4032AEC52C8F6F44F77612845D</sign>\n   <mch_id>10019872</mch_id>\n   <body>苹果</body>\n   <spbill_create_ip>192.168.1.119</spbill_create_ip>\n   <total_fee>1</total_fee>\n   <notify_url>http://xiao501849930.vicp.cc/zxims/f/site/shopping/wxNotify</notify_url>\n   <appid>wxc5822a0e936601fd</appid>\n   <openid>opGpjuKgC11nzeQlDJ82AplGSyZ8</openid>\n   <out_trade_no>1514120141114090342</out_trade_no>\n   <nonce_str>WhGx0vhJHPyaDiyj</nonce_str>\n   <trade_type>JSAPI</trade_type>\n</xml>\n";
		
     	 String xmlParam = formatParam(parameters, ApiKey);
        String result = HttpRequest.postXml("https://api.mch.weixin.qq.com/pay/unifiedorder", test);
        
        Map<String, String> map =  XMLUtils.xml2Map(result);
        
		
		return map.get("xml.code_url");
	}
	
	
	/**
	 * 刷卡支付API
	 * @return
	 * @throws Exception
	 */
	public Map<String, String> createMicropayAPI() throws Exception{
		String str = CommonUtil.CreateNoncestr();
		
		init(parameters);
        
        String xmlParam = formatParam(parameters, ApiKey);
        System.out.println(xmlParam);
        String result = HttpRequest.postXml("https://api.mch.weixin.qq.com/pay/micropay", xmlParam);
        
        result = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg><appid><![CDATA[wx1e519a27efb281ee]]></appid><mch_id><![CDATA[1401694802]]></mch_id><sub_mch_id><![CDATA[1418763902]]></sub_mch_id><device_info><![CDATA[30]]></device_info><nonce_str><![CDATA[6EshfkkSHJU3LhN0]]></nonce_str><sign><![CDATA[00DACBCBE474145842ADC0FFD7C346CE]]></sign><result_code><![CDATA[SUCCESS]]></result_code><openid><![CDATA[oV1IOw_GAk9CDs7tIwrl4wtERMsQ]]></openid><is_subscribe><![CDATA[Y]]></is_subscribe><trade_type><![CDATA[MICROPAY]]></trade_type><bank_type><![CDATA[CFT]]></bank_type><total_fee>2</total_fee><fee_type><![CDATA[CNY]]></fee_type><transaction_id><![CDATA[4001912001201702210778076811]]></transaction_id><out_trade_no><![CDATA[3020170221163804379]]></out_trade_no><attach><![CDATA[]]></attach><time_end><![CDATA[20170221163805]]></time_end><sub_appid><![CDATA[wx21479772672ace30]]></sub_appid><sub_openid><![CDATA[oUucDwJigYHLuuKDWZxb2S5T6InQ]]></sub_openid><sub_is_subscribe><![CDATA[Y]]></sub_is_subscribe><cash_fee>2</cash_fee><cash_fee_type><![CDATA[CNY]]></cash_fee_type></xml>";
        //result = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg><appid><![CDATA[wx1e519a27efb281ee]]></appid><mch_id><![CDATA[1401694802]]></mch_id><sub_mch_id><![CDATA[1418763902]]></sub_mch_id><device_info><![CDATA[30]]></device_info><nonce_str><![CDATA[fS0x34Tm1UeLZIxb]]></nonce_str><sign><![CDATA[ACF969B0CA14F5D1A977457D35AB092F]]></sign><result_code><![CDATA[FAIL]]></result_code><err_code><![CDATA[USERPAYING]]></err_code><err_code_des><![CDATA[需要用户输入支付密码]]></err_code_des><sub_appid><![CDATA[wx21479772672ace30]]></sub_appid></xml>";
        
        Map<String, String> xmlMap =  XMLUtils.xml2Map(result);
        return xmlMap;
	}
	
	/**
	 * 刷卡支付--授权码查询OPENID接口
	 * @return
	 * @throws Exception
	 */
	public Map<String, String> authcodetoopenid() throws Exception{
		
		String str = CommonUtil.CreateNoncestr();
		
		init(parameters);
        
        String xmlParam = formatParam(parameters, ApiKey);
        System.out.println(xmlParam);
        String result = HttpRequest.postXml("https://api.mch.weixin.qq.com/tools/authcodetoopenid", xmlParam);
        Map<String, String> xmlMap =  XMLUtils.xml2Map(result);
        return xmlMap;
	}
	
	/**
	 * 刷卡支付--查询订单
	 * @return
	 * @throws Exception
	 */
	public Map<String, String> orderquery() throws Exception{
		String str = CommonUtil.CreateNoncestr();
		init(parameters);
        
        String xmlParam = formatParam(parameters, ApiKey);
        System.out.println(xmlParam);
        String result = HttpRequest.postXml("https://api.mch.weixin.qq.com/pay/orderquery", xmlParam);
        Map<String, String> xmlMap =  XMLUtils.xml2Map(result);
        return xmlMap;
	}
	
	/**
	 * 小程序 微信支付接口
	 * @return
	 * @throws Exception
	 */
	public Map createPayByJSAPI() throws Exception{
		String str = CommonUtil.CreateNoncestr();
		
		init(parameters);
        
        String xmlParam = formatParam(parameters, ApiKey);
        System.out.println(xmlParam);
        String result = HttpRequest.postXml("https://api.mch.weixin.qq.com/pay/unifiedorder", xmlParam);
        System.out.println(result);
        Map<String, String> xmlMap =  XMLUtils.xml2Map(result);
        
		HashMap<String, String> map = new HashMap<String, String>();
		map.put("appId", AppId);//微信分配的公众账号 ID
		map.put("timeStamp", System.currentTimeMillis()+"");//商品描述
        map.put("nonceStr", str);//随机字符串
        map.put("signType", "MD5");//商户系统内部的订单号
        map.put("package", "prepay_id="+xmlMap.get("xml.prepay_id"));//订单总金额  单位为分
        
        String param = CommonUtil.FormatBizQueryParaMap(map,false,false);
		String sign = MD5SignUtil.Sign(param, ApiKey);
		
		System.out.println(param);
		
		map.put("paySign", sign);
		
		return map;
	}
	
	/**
	 * 服务商支付
	 * @return
	 * @throws Exception
	 */
	public Map createServicePayByJSAPI() throws Exception{
		String str = CommonUtil.CreateNoncestr();
		
		init(parameters);
        
        String xmlParam = formatParam(parameters, ApiKey);
        System.out.println(xmlParam);
        String result = HttpRequest.postXml("https://api.mch.weixin.qq.com/pay/unifiedorder", xmlParam);
        System.out.println(result);
        Map<String, String> xmlMap =  XMLUtils.xml2Map(result);
        
		HashMap<String, String> map = new HashMap<String, String>();
		map.put("appId", parameters.get("sub_appid"));//微信分配的公众账号 ID
		map.put("timeStamp", System.currentTimeMillis()+"");//商品描述
        map.put("nonceStr", str);//随机字符串
        map.put("signType", "MD5");//商户系统内部的订单号
        map.put("package", "prepay_id="+xmlMap.get("xml.prepay_id"));//订单总金额  单位为分
        
        String param = CommonUtil.FormatBizQueryParaMap(map,false,false);
		String sign = MD5SignUtil.Sign(param, ApiKey);
		
		System.out.println(param);
		
		map.put("paySign", sign);
		
		return map;
	}
	
	public String createPayUrlByJSAPI() throws Exception{
		String str = CommonUtil.CreateNoncestr();
		
		init(parameters);
        
        String xmlParam = formatParam(parameters, ApiKey);
        System.out.println(xmlParam);
        String result = HttpRequest.postXml("https://api.mch.weixin.qq.com/pay/unifiedorder", xmlParam);
        System.out.println(result);
        Map<String, String> xmlMap =  XMLUtils.xml2Map(result);
        
		HashMap<String, String> map = new HashMap<String, String>();
		 map.put("appId", AppId);//微信分配的公众账号 ID
		 map.put("timeStamp", System.currentTimeMillis()+"");//商品描述
        map.put("nonceStr", str);//随机字符串
        map.put("signType", "MD5");//商户系统内部的订单号
        map.put("package", "prepay_id="+xmlMap.get("xml.prepay_id"));//订单总金额  单位为分
        
        String param = CommonUtil.FormatBizQueryParaMap(map,false,false);
		String sign = MD5SignUtil.Sign(param, ApiKey);
		
		System.out.println(param);
		
		map.put("paySign", sign);
		
		return JSON.toJSONString(map);
	}
	
	public Map<String,String> applyRefund(String certFile,String outRefundNo, String transactionId, String outTradeNo, String totalFee, String refundFee){
		String postUrl = "https://api.mch.weixin.qq.com/secapi/pay/refund";//微信退款
		
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("appid", AppId);			
		map.put("mch_id",MchId);			
		map.put("nonce_str", MoneyUtils.buildRandom());
		map.put("out_refund_no",outRefundNo);				//商户退款单号
		map.put("refund_fee", refundFee);				//退款金额
		map.put("total_fee", totalFee);					//总金额
		map.put("sign", MoneyUtils.createSign(map,ApiKey));
		if(StringUtils.isNotBlank(transactionId)){
			map.put("transaction_id", transactionId);		//微信订单号
		}else{
			map.put("out_trade_no", outTradeNo);			//商户订单号
		}
		map.put("sign", MoneyUtils.createSign(map,ApiKey));
		
		Map<String,String> params =  new HashMap<String, String>();
		try {
			System.out.println(MoneyUtils.createXML(map));
			String result = MoneyUtils.doSendMoney(postUrl, MoneyUtils.createXML(map),MchId,certFile);
			System.out.println("result:"+result);
			Map<String,String> mapTwo = XMLUtils.xml2Map(result);
			return mapTwo;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	public static void main(String[] args) throws Exception {
		
		String str = CommonUtil.CreateNoncestr();
		
		
		
	}
	
	
	
}
